package com.example.wisdombookstore.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.wisdombookstore.entity.TbShoppingCart;
import com.example.wisdombookstore.entity.TbUser;
import com.example.wisdombookstore.mapper.TbUserMapper;
import com.example.wisdombookstore.service.IShoppingCartService;
import com.example.wisdombookstore.service.IUserService;
import com.example.wisdombookstore.util.*;
import com.example.wisdombookstore.util.face.GetToken;
import com.example.wisdombookstore.util.face.GsonUtils;
import com.example.wisdombookstore.util.face.HttpUtil;
import com.example.wisdombookstore.util.face.Service.LoginService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements IUserService {

    @Autowired
    private TbUserMapper tbUserMapper;
    @Autowired
    private IShoppingCartService iShoppingCartService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    LoginService loginService = null;
    @Autowired
    private IdWorker idWorker;
    @Value("${keyPath}")
    private String keyPath;

    /**
     * TODO &宋合& 手机发送验证码
     *
     * @param phone:
     * @Description:
     * @Author: 宋合
     * @Date: 2020/10/22 19:11
     * @return: com.example.wisdombookstore.util.ResponseResult
     **/
    @Override
    public ResponseResult sendMobileVerificationCode(String phone) {

        ResponseResult result = new ResponseResult();
        //验证是否注册
        TbUser user = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda()
                        .eq(TbUser::getMobile, phone)
                        .last("limit 1")
        );
        //--2 保存手机号
        if (user == null) {
            //随机生成验证码
            try {
                Integer icode = (int) ((Math.random() * 9 + 1) * 100000);
                //发送验证码
                SmsUtil.sendSmsBySanWu(phone, String.valueOf(icode));
                result.setResult("手机号为" + phone + "验证码为" + icode);
                String key = "code_" + phone;
                //--3 保存验证码（redis，过期时间5分钟
                redisTemplate.opsForValue().set(key, icode + "", 60 * 5, TimeUnit.SECONDS);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
                result.setFailMessage("发送失败，请核对手机号");
                return result;
            }

        }
        result.setFailMessage("该手机号已注册");
        return result;

    }

    /**
     * TODO &宋合& 手机注册
     *
     * @param phone:            手机号
     * @param verificationCode: 验证码
     * @Description:
     * @Author: 宋合
     * @Date: 2020/10/22 10:41
     * @return: com.example.wisdombookstore.util.ResponseResult
     **/
    @Override
    public ResponseResult telRegister(String phone, String verificationCode) {
        ResponseResult result = new ResponseResult();
        try {
            System.out.println(phone + verificationCode);
            //获取验证码
            String s = redisTemplate.opsForValue().get("code_" + phone);
            System.out.println(s);
            //判断是否为空
            if (s != null) {
                //验证码是否正确
                if (verificationCode.equals(s)) {
                    TbUser newUser = new TbUser();
                    newUser.setCode(idWorker.nextId());
                    newUser.setMobile(phone);
                    newUser.setPwd("123456");


                    //注册
                    tbUserMapper.insert(newUser);
                    TbShoppingCart tbShoppingCart = new TbShoppingCart();
                    tbShoppingCart.setCode(idWorker.nextId());
                    tbShoppingCart.setTbUserCode(newUser.getCode());
                    iShoppingCartService.save(tbShoppingCart);
                    result.setResult(newUser);
                    return result;
                }
                result.setFailMessage("验证码错误");
            }
            result.setFailMessage("验证码已失效");
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.setFailMessage("注册失败");
            return result;
        }
    }

    /**
     * TODO &宋合& 微信注册
     *
     * @param wechatCode: 微信号
     * @Description:
     * @Author: 宋合
     * @Date: 2020/10/22 10:44
     * @return: com.example.wisdombookstore.util.ResponseResult
     **/
    @Override
    public ResponseResult wechatRegister(String wechatCode) {
        ResponseResult responseResult = new ResponseResult();
        try {
            //查询是否注册
            List<TbUser> tbUsers = tbUserMapper.selectList(new QueryWrapper<TbUser>().lambda().eq(TbUser::getWeChatCode, wechatCode));
            if (tbUsers.size() > 0) {
                responseResult.setFailMessage("该微信号已注册");
                return responseResult;
            }
            TbUser tbUser = new TbUser();
            //注册
            tbUser.setCode(idWorker.nextId());
            tbUser.setWeChatCode(wechatCode);
            tbUserMapper.insert(tbUser);
            //添加购物车
            TbShoppingCart tbShoppingCart = new TbShoppingCart();
            tbShoppingCart.setCode(idWorker.nextId());
            tbShoppingCart.setTbUserCode(tbUser.getCode());
            iShoppingCartService.save(tbShoppingCart);
            responseResult.setResult(tbUser);
            return responseResult;
        } catch (Exception e) {
            e.printStackTrace();
            responseResult.setFailMessage("注册失败");
            //查询是否注册
            return responseResult;
        }
    }

    /**
     * TODO &宋合& 手机号登录
     *
     * @param user: 用户
     * @Description:
     * @Author: 宋合
     * @Date: 2020/10/22 10:47
     * @return: com.example.wisdombookstore.util.ResponseResult
     **/

    @Override
    public ResponseResult telLogin(TbUser user) {
        ResponseResult responseResult = new ResponseResult();
        try {
            //验证登录
            List<TbUser> tbUsers = tbUserMapper.selectList(new QueryWrapper<TbUser>().lambda().eq(TbUser::getMobile, user.getMobile()).eq(TbUser::getPwd, user.getPwd()));
            if (tbUsers.size() > 0) {
                //登录成功
                responseResult.setResult(tbUsers);
                return responseResult;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        responseResult.setFailMessage("用户名或密码错误");
        return responseResult;
    }

    /**
     * TODO &宋合&
     *
     * @param wechatId:
     * @Description: 微信登录
     * @Author: 宋合
     * @Date: 2020/10/23 9:04
     * @return: com.example.wisdombookstore.util.ResponseResult
     **/
    @Override
    public ResponseResult wechatLogin(String wechatId) {
        ResponseResult responseResult = new ResponseResult();

        try {
            List<TbUser> tbUsers = tbUserMapper.selectList(new QueryWrapper<TbUser>().lambda().eq(TbUser::getWeChatCode, wechatId));
            if (tbUsers != null) {
                responseResult.setResult(tbUsers);
                return responseResult;
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
        responseResult.setFailMessage("微信登录失败");
        return responseResult;
    }

    @Override
    public ResponseResult createQrcode(String phone) {
        ResponseResult responseResult = new ResponseResult();
        String path = UUID.randomUUID() + "";
        String text = phone;
        // 嵌入二维码的图片路径
        String src = keyPath;
        String imgPath = src + "book.jfif";
        // 生成的二维码的路径及名称
        String destPath = src + path + ".jpg";
        InputStream inputStream = null;
        String str = null;
        String url= null;
        try {
            String endpoint = "http://oss-cn-beijing.aliyuncs.com";
            // 云账号AccessKey有所有API访问权限，建议遵循阿里云安全最佳实践，创建并使用RAM子账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建。
            String accessKeyId = "LTAI4G9iRdw7vLeENqbeou94";
            String accessKeySecret = "qchG9Za2QmRh5lLSnitQSj0Drc6k5X";
        /*LTAI4G9iRdw7vLeENqbeou94
          qchG9Za2QmRh5lLSnitQSj0Drc6k5X*/
            // 创建OSSClient实例。
            QRCodeUtil.encode(text, imgPath, destPath, true);
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            inputStream = new FileInputStream(destPath);
            //生成二维码


            // 解析二维码
            str = QRCodeUtil.decode(destPath);
            url="https://songhe.oss-cn-beijing.aliyuncs.com/"+path + ".jpg";
            System.out.println(url);
            ossClient.putObject("songhe", path + ".jpg", inputStream);
            ossClient.shutdown();
            if(url==null){
                responseResult.setFailMessage("生成失败");
                return responseResult;
            }
            responseResult.setResult(url);
            return responseResult;
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 打印出解析出的内容
        responseResult.setFailMessage("生成失败！！！");
        return responseResult;
    }

    @Override
    public ResponseResult faceRecognition(String faceUrl) {
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try {
            in = new FileInputStream(faceUrl);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String s = new String(Base64.encodeBase64(data));

        return null;
    }

    @Override
    public ResponseResult payBooks(Long tbOrderCode, double money, String payCode) {
        return null;
    }


    public static void main(String[] args) {
        String faceUrl = "D:/fileDB/aaa.png";
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try {
            in = new FileInputStream(faceUrl);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String s = new String(Base64.encodeBase64(data));
        String host = "https://zfa.market.alicloudapi.com";
        String path = "/efficient/idfaceIdentity";
        String method = "POST";
        String appcode = "2bf8cde064e64b4e90585d8deee4f7f1";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("base64Str", "urlencode(" + s + ")");
        bodys.put("liveChk", "1");
        bodys.put("name", "宋合");
        bodys.put("number", "130726199810050010");


        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtilsNote.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public ResponseResult getUserList(Integer pageSize, Integer pageCurrent) {
        ResponseResult responseResult = new ResponseResult();

        try {
            PageHelper.startPage(pageSize, pageCurrent);
            List<TbUser> tbUsers = tbUserMapper.selectList(null);
            PageInfo<TbUser> tbUserPageInfo = new PageInfo<>(tbUsers);
            responseResult.setResult(tbUserPageInfo);
            return responseResult;
        } catch (Exception e) {
            e.printStackTrace();
        }

        PageHelper.startPage(pageSize, pageCurrent);
        List<TbUser> tbUsers = tbUserMapper.selectList(null);
        PageInfo<TbUser> tbUserPageInfo = new PageInfo<>(tbUsers);
        responseResult.setResult(tbUserPageInfo);

        return responseResult;
    }

    @Override
    public ResponseResult getUserById(Long tbUserCode) {
        ResponseResult responseResult = new ResponseResult();
        try {
            QueryWrapper<TbUser> queryWrapper = new QueryWrapper<>();
            //1.判断该用户是否存在或是否删除
            queryWrapper.lambda().eq(TbUser::getCode, tbUserCode).ne(TbUser::getIsDel, StateConstant.OBJECT_DEL_OMIT);
            TbUser tbUser = tbUserMapper.selectOne(queryWrapper);
            if (tbUser == null) {
                responseResult.setFailMessage("此人不存在");
                return responseResult;
            }
            responseResult.setResult(tbUser);
            return responseResult;
        } catch (Exception e) {
            e.printStackTrace();
        }
        responseResult.setFailMessage("查询失败");
        return responseResult;
    }

    @Override
    public ResponseResult setUserById(TbUser user) {
        ResponseResult responseResult = new ResponseResult();
        try {

            tbUserMapper.updateById(user);
            responseResult.setResult(user);
            return responseResult;
        } catch (Exception e) {
            e.printStackTrace();
        }
        responseResult.setFailMessage("");
        return responseResult;
    }

    @Override
    public ResponseResult addUserById(TbUser user) {
        ResponseResult responseResult = new ResponseResult();
        try {
            tbUserMapper.updateById(user);
            responseResult.setResult(user);
            return responseResult;
        } catch (Exception e) {
            e.printStackTrace();
        }
        responseResult.setResult("添加失败");
        return responseResult;
    }

    @Override
    public ResponseResult delUserById(Long user) {

        ResponseResult responseResult = new ResponseResult();
        try {
            QueryWrapper<TbUser> tbUserQueryWrapper = new QueryWrapper<>();
            tbUserQueryWrapper.lambda().eq(TbUser::getCode, user);
            TbUser tbUser = tbUserMapper.selectOne(tbUserQueryWrapper);
            if (tbUser != null) {
                tbUser.setState(1);
                tbUserMapper.updateById(tbUser);
                responseResult.setResult(tbUser);
                return responseResult;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        responseResult.setResult("停用失败");
        return responseResult;
    }

    @Override
    public String faceAuthentication(StringBuffer imageBast64, Model model, HttpServletRequest request, Long userCode) throws IOException {
        String substring = imageBast64.substring(imageBast64.indexOf(",") + 1, imageBast64.length());
        // 请求url
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add";
        try {
            QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(TbUser::getCode, userCode);
            System.out.println("=========================" + userCode);
            TbUser tbUser = tbUserMapper.selectOne(wrapper);
            System.out.println("=========================" + tbUser);

            Map<String, Object> map = new HashMap<>();
            map.put("image", substring);
            map.put("group_id", "TheShy");
            map.put("user_id", userCode);
            map.put("user_info", "abc");
            map.put("liveness_control", "NONE");
            map.put("image_type", "BASE64");
            map.put("quality_control", "NONE");
            //判断用户是否存在
            if (tbUser == null) {
                map.remove("image");
                map.put("error", true);
            }
            map.put("user", tbUser);
            System.out.println("========登录成功" + tbUser);

            String param = GsonUtils.toJson(map);


            // 注意这里仅为了简化编码每一次请求都去获取access_token，线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取。
            String accessToken = GetToken.getAuth();

            String result = HttpUtil.post(url, accessToken, "application/json", param);
            System.out.println(result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String searchFace(StringBuffer imageBast64, Model model, HttpServletRequest request) throws IOException {
        Map<String, Object> searchface = loginService.searchface(imageBast64);
        if (searchface == null || searchface.get("user_id") == null) {
            System.out.println("我进来了");
            String flag = "fail";
            String s = GsonUtils.toJson(flag);
            return s;
        }
        String user_id = searchface.get("user_id").toString();

        String score = searchface.get("score").toString().substring(0, 2);
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbUser::getCode, user_id);
        TbUser user = tbUserMapper.selectOne(wrapper);
        int i = Integer.parseInt(score);
        if (i > 80) {
            model.addAttribute("userinf", user_id);
            HttpSession session = request.getSession();
            session.setAttribute("userinf", user_id);
            session.setAttribute("userName",user.getName());
            System.out.println("存入session");
        }

        System.out.println(searchface);
        //判断用户是否存在
        if (user == null) {
            searchface.put("error", true);
        }
        String s = GsonUtils.toJson(searchface);
        return s;
    }

    @Override
    public ResponseResult upload(MultipartFile file) {
        ResponseResult responseResult = new ResponseResult();

        try {
            String ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            //获取路径
            String dirPath = keyPath;
            String path = UUID.randomUUID() + ext;
            //将文件复制到对应服务器下
            File mFile = new File(dirPath + path);
            //将文件的存储路径返回给前端
            file.transferTo(mFile);
            Map<String, Object> map = new HashMap<>();
            map.put("path", path);
            responseResult.setResult(map);
            return responseResult;
        } catch (IOException e) {
            e.printStackTrace();
        }
        responseResult.setFailMessage("上传错误");

        return responseResult;
    }

    @Override
    public ResponseResult download(String image, HttpServletResponse response) {
        ResponseResult responseResult = new ResponseResult();
        try {
            //读取图片流
            FileInputStream fileInputStream = new FileInputStream(keyPath + image);
            byte[] b = new byte[1024];//定义每次读取流中的多少字节
            int len;//记录每次读取多少字节字节流的位置
            while ((len = fileInputStream.read(b)) > 0) {
                System.out.println(len);
                System.out.println("---------------------");
                response.getOutputStream().write(b, 0, len);
            }

            //将文件流写到响应输出流中

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public ResponseResult ossUpload(MultipartFile file) {
        ResponseResult responseResult = new ResponseResult();
        String ext=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String endpoint = "http://oss-cn-beijing.aliyuncs.com";
        // 云账号AccessKey有所有API访问权限，建议遵循阿里云安全最佳实践，创建并使用RAM子账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建。
        String accessKeyId = "LTAI4G9iRdw7vLeENqbeou94";
        String accessKeySecret = "qchG9Za2QmRh5lLSnitQSj0Drc6k5X";
        /*LTAI4G9iRdw7vLeENqbeou94
          qchG9Za2QmRh5lLSnitQSj0Drc6k5X*/
        // 创建OSSClient实例。
        String path=UUID.randomUUID()+ext;
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流。
//        InputStream inputStream = null;
        String url=null;

        try {
//            inputStream = new FileInputStream("F:\\壁纸\\gamersky_02origin_03_2016792052840.jpg");

            url="https://songhe.oss-cn-beijing.aliyuncs.com/"+path;
            ossClient.putObject("songhe", path, file.getInputStream());
            ossClient.shutdown();
            if(url==null){
               responseResult.setFailMessage("上传失败");
               return responseResult;
            }
            System.out.println(url);
            responseResult.setResult(url);
            return responseResult;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 关闭OSSClient。
        responseResult.setFailMessage("上传失败");
        return responseResult;
    }

}
